package org.dding.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dding.core.log.ILogger;
import org.dding.core.log.LoggerFactory;
import org.dding.core.util.StandaloneXmlParser.DataSourceConfig.PoolConfig;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class StandaloneXmlParser {

	private static ILogger logger = LoggerFactory
			.getLogger(StandaloneXmlParser.class);
	private static final String EXTENSIONS = "extensions";
	private static final String EXTENSION = "extension";
	private static final String DATASOURCES = "datasources";
	private static final String DATASOURCE = "datasource";
	private static final String POOL = "pool";
	private static final String PROPERTY = "property";
	private static List<DataSourceConfig> datasourceConfig = new ArrayList<DataSourceConfig>();
	private static Document document;
	static List<Extension> extensionlist = new ArrayList<Extension>();

	public static List<DataSourceConfig> getDataSourceConfig() {
		return datasourceConfig;
	}

	public static void parser(String path) {
		try {
			document = XMLUtils
					.loadDocument(new FileInputStream(new File(path)));
		} catch (Exception e) {
			logger.warn(e, "parser document failure");
		}
		parserExtension();
		parserDatasource();
	}

	public static List<Extension> getExtensionlist() {
		return extensionlist;
	}

	/**
	 * <datasources id="jboss:domain:datasources:1.0">
		<datasource name="datasource" pool-name="H2DS" enabled="true">
			<connection-url>jdbc:hsqldb:hsql://localhost/cms</connection-url>
			<driver>org.hsqldb.jdbc.JDBCDriver</driver>
			<username>sa</username>
			<password>sa</password>
		</datasource>
	</datasources>
	 */
	static void parserDatasource() {

		Element elementDatasources = XMLUtils.getElementByTagName(
				document.getDocumentElement(), DATASOURCES);
		if (elementDatasources == null) {
			logger.debug("can't find any datasource.");
			return;
		}

		List<Element> datasources = XMLUtils.getElementsByTagName(
				elementDatasources, DATASOURCE);
		for (Element source : datasources) {
			DataSourceConfig config = new DataSourceConfig();
			config.name = source.getAttribute("name");
			config.jndi = source.getAttribute("jndi-name");
			config.pool_name = source.getAttribute("pool-name");
			if (!StringUtils.isEmpty(config.pool_name))
				config.poolConfig = parserPool(config);
			config.enable = Boolean
					.parseBoolean(source.getAttribute("enabled"));
			Element url = XMLUtils
					.getElementByTagName(source, "connection-url");
			if (url != null)
				config.url = url.getTextContent();
			Element driver = XMLUtils.getElementByTagName(source, "driver");
			if (driver != null)
				config.driver = driver.getTextContent();
			Element username = XMLUtils.getElementByTagName(source, "username");
			if (username != null)
				config.username = username.getTextContent();
			Element password = XMLUtils.getElementByTagName(source, "password");
			if (password != null)
				config.password = password.getTextContent();
			datasourceConfig.add(config);
		}
	}

	static DataSourceConfig.PoolConfig parserPool(DataSourceConfig config) {

		Element pool = XMLUtils.getElementByTagName(
				document.getDocumentElement(), POOL);
		if (pool == null) {
			logger.info("can't find pool config " + config.pool_name);
			return null;
		}
		PoolConfig poolConfig = config.new PoolConfig();
		poolConfig.id = pool.getAttribute("id");
		List<Element> properties = XMLUtils.getChildElementsByTagName(pool,
				PROPERTY);
		for (Element element : properties) {
			poolConfig.addProperty(element.getAttribute("name"),
					element.getAttribute("value"));
		}
		return poolConfig;
	}

	static void parserExtension() {

		Element elementExtensions = XMLUtils.getElementByTagName(
				document.getDocumentElement(), EXTENSIONS);
		if (elementExtensions == null) {
			logger.debug("can't find any extension.");
			return;
		}
		List<Element> extensions = XMLUtils.getElementsByTagName(
				elementExtensions, EXTENSION);
		if (extensions == null)
			return;

		for (Element element : extensions) {
			String moduleName = XMLUtils.getAtrributeValue(element, "module");
			String unzip = XMLUtils.getAtrributeValue(element, "unzip");
			boolean isUnzip = Boolean.parseBoolean(unzip);
			Extension extension = new Extension(moduleName, isUnzip);
			extensionlist.add(extension);
		}
	}

	static public class DataSourceConfig {
		public String name;
		public String pool_name;
		public boolean enable;
		public String jndi;
		public String url;
		public String username;
		public String password;
		public String driver;
		public PoolConfig poolConfig;

		public class PoolConfig {
			Map<String, String> poolProperties = new HashMap<String, String>();

			public Map<String, String> getPoolProperties() {
				return poolProperties;
			}

			public String id;

			public void addProperty(String key, String value) {
				poolProperties.put(key, value);
			}

			public String getProperty(String key) {
				return poolProperties.get(key);
			}
		}
	}

	static public class Extension {
		public String moduleName;
		public boolean unzip;

		public Extension(String moduleName, boolean unzip) {
			super();
			this.moduleName = moduleName;
			this.unzip = unzip;
		}

	}
}
